package whu.cachhe.makeorder.ui;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import whu.cachhe.makeorder.R;
import whu.cachhe.makeorder.domain.Parking;
import whu.cachhe.makeorder.domain.ParkingLot;
import whu.cachhe.makeorder.net.HttpRequest;
import whu.cachhe.makeorder.net.URLConstant;
import whu.cachhe.makeorder.view.GalleryView;
import whu.cachhe.makeorder.view.SimpleDateTimePicker;
import whu.cachhe.makeorder.view.XRadioGroup;

public class ParkingActivity extends AppCompatActivity {
    private Toolbar toolbar;
    private GalleryView galleryView;
    private XRadioGroup xRadioGroup;
    private Button btnToReserve;
    private TextView tvStartTime, tvEndTime;

    private int checkedPosition = -1;

    private SimpleDateTimePicker timePicker;
    private Date startTime, endTime;
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    private Parking parking;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_parking);

        init();

        try {
            parking = getIntent().getParcelableExtra("parking");
            if (parking != null){
                toolbar.setTitle(parking.getName());
                setSupportActionBar(toolbar);

                final List<String> imgURLs = parking.getImgURLs();
                galleryView.bindData(new SimpleGalleryAdapter(ParkingActivity.this) {
                    @Override
                    public int getCount() {
                        return imgURLs.size();
                    }

                    @Override
                    public void bindDataToEachView(Object viewHolder, int position) {
                        ParkingActivity.ViewHolder holder = (ParkingActivity.ViewHolder) viewHolder;
                        Glide.with(ParkingActivity.this)
                                .load(imgURLs.get(position))
                                .placeholder(R.mipmap.defalut)
                                .error(R.mipmap.defalut)
                                .into(holder.imgPhoto);
                    }
                });

                getParkingById(parking.getPid());
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void init(){
        toolbar = findViewById(R.id.toolbar);
//        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        galleryView = findViewById(R.id.gallery_view);
        galleryView.setNumOfItemViews(1);

        xRadioGroup = findViewById(R.id.ll_list_view);
        xRadioGroup.setOnCheckedChangeListener(new XRadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(XRadioGroup group, int checkedId) {
                int lastCheckedPosition = checkedPosition;
                checkedPosition = group.getCheckedPosition();

                if (lastCheckedPosition != checkedPosition){
                    timePicker.setExcludeTime(parking.getParkingLots().get(checkedPosition).getOccupiedTime());

                    endTime = startTime = null;
                    tvStartTime.setText("开始时间");
                    tvEndTime.setText("结束时间");
                    btnToReserve.setEnabled(false);

                    GalleryView galleryView;
                    // 关闭上次checked
                    View lastView = group.getChildAt(lastCheckedPosition);
                    if(lastView != null){
                        galleryView = lastView.findViewById(R.id.gallery_view);
                        if (galleryView != null)
                            galleryView.setVisibility(View.GONE);
                    }

                    // 展示这次checked 图片
                    View itemView = group.getChildAt(checkedPosition);
                    galleryView = itemView.findViewById(R.id.gallery_view);
                    if (galleryView != null && !galleryView.isEmpty())
                        galleryView.setVisibility(View.VISIBLE);
                }
            }
        });

        timePicker = new SimpleDateTimePicker(ParkingActivity.this);

        tvStartTime = findViewById(R.id.tv_start_time);
        tvStartTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isParkingLotChecked())
                    return;

                timePicker.setTitle("选择开始时间");
                timePicker.setTimeType(SimpleDateTimePicker.TIME_TYPE.START_TIME);
                timePicker.setOnDateTimeSelectedListener(new SimpleDateTimePicker.OnDateTimeSelectedListener() {
                    @Override
                    public void onDateTimeSelected(int year, int month, int dayOfMonth, int hourOfDay, int minute) {
                        try {
                            startTime = dateFormat.parse(
                                    String.format("%d-%d-%d %02d:%02d", year, month + 1, dayOfMonth, hourOfDay, minute));
                            tvStartTime.setText(dateFormat.format(startTime));
                            timePicker.setStartTime(startTime);

                            endTime = null;
                            tvEndTime.setText("结束时间");

                            refreshReserveAbility();
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }

                    }
                });
                timePicker.show();
            }
        });
        tvEndTime = findViewById(R.id.tv_end_time);
        tvEndTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isParkingLotChecked())
                    return;

                if (startTime == null){
                    showErrorDialog("请先选择开始时间");
                    return;
                }

                timePicker.setTitle("选择结束时间");
                timePicker.setTimeType(SimpleDateTimePicker.TIME_TYPE.END_TIME);
                timePicker.setOnDateTimeSelectedListener(new SimpleDateTimePicker.OnDateTimeSelectedListener() {
                    @Override
                    public void onDateTimeSelected(int year, int month, int dayOfMonth, int hourOfDay, int minute) {
                        try {
                            endTime = dateFormat.parse(
                                    String.format("%d-%d-%d %02d:%02d", year, month + 1, dayOfMonth, hourOfDay, minute));
                            tvEndTime.setText(dateFormat.format(endTime));

                            refreshReserveAbility();
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    }
                });
                timePicker.show();
            }
        });

        btnToReserve = findViewById(R.id.btn_to_reserve);
        btnToReserve.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    String selectedLotId = parking.getParkingLots().get(checkedPosition).getLotId();
                    reserveParkingLotById(selectedLotId, dateFormat.format(startTime), dateFormat.format(endTime));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void refreshReserveAbility(){
        if (startTime != null && endTime != null)
            btnToReserve.setEnabled(true);
        else
            btnToReserve.setEnabled(false);
    }

    private void bindLinearLayout(XRadioGroup xRadioGroup, List<ParkingLot> data){
        xRadioGroup.removeAllViews();
        for (int i = 0; i < data.size(); i++){
            ViewGroup contentView = (ViewGroup) View.inflate(ParkingActivity.this, R.layout.item_parking_lot, null);
            TextView tvName = contentView.findViewById(R.id.tv_name);
            GalleryView galleryView = contentView.findViewById(R.id.gallery_view);
            galleryView.setNumOfItemViews(2);

            ParkingLot parkingLot = data.get(i);
            final List<String> imgURLs = parkingLot.getImgURLs();
            if (imgURLs != null && !imgURLs.isEmpty()){
                galleryView.bindData(new SimpleGalleryAdapter(ParkingActivity.this, galleryView.getLayoutParams().height) {
                    @Override
                    public int getCount() {
                        return imgURLs.size();
                    }

                    @Override
                    public void bindDataToEachView(Object viewHolder, int position) {
                        ParkingActivity.ViewHolder holder = (ParkingActivity.ViewHolder) viewHolder;
                        Glide.with(ParkingActivity.this)
                                .load(imgURLs.get(position))
                                .placeholder(R.mipmap.defalut)
                                .error(R.mipmap.defalut)
                                .into(holder.imgPhoto);
                    }
                });
            }
            tvName.setText(parkingLot.getName());

            xRadioGroup.addView(contentView); // 加缓存
        }
    }

    private void showErrorDialog(String message){
        new AlertDialog.Builder(ParkingActivity.this)
                .setTitle("提示")
                .setMessage(message)
                .setPositiveButton("返回", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                })
                .show();
    }

    private boolean isParkingLotChecked(){
        if (checkedPosition == -1){
            showErrorDialog("请先选择一个车位");
            return false;
        } else
            return true;
    }

    private abstract static class SimpleGalleryAdapter implements GalleryView.OnBindEachViewData {
        private Context context;
        private int height = -3;

        public SimpleGalleryAdapter(Context context){
            this.context = context;
        }

        public SimpleGalleryAdapter(Context context, int height){
            this.context = context;
            this.height = height;
        }

        @Override
        public View getView() {
            return View.inflate(context, R.layout.view_gallery_image, null);
        }

        @Override
        public Object getViewHolder(View view) {
            ViewHolder holder = new ViewHolder();
            holder.imgPhoto = view.findViewById(R.id.img_photo);
            if (height != -3){
                ViewGroup.LayoutParams params = holder.imgPhoto.getLayoutParams();
                params.height = height;
                holder.imgPhoto.setLayoutParams(params);
            }
            return holder;
        }
    }

    private static class ViewHolder{
        ImageView imgPhoto;
    }

    /**
     * 这个接口考虑更改为只查询停车场的车位信息
     * @param pid
     * @throws JSONException
     */
    private void getParkingById(String pid) throws JSONException {
        JSONObject fparam = new JSONObject();
        fparam.put("uid", MainActivity.user.getReserveSysId())
                .put("pid", pid);

        HttpRequest.post(URLConstant.HOST, "getParkingById", fparam, new HttpRequest.HttpRequestCallback() {
            @Override
            public void onSuccess(JSONObject response) {
                if (response.optInt("success") == 1){
                    JSONObject jParking = response.optJSONObject("result");
//                    parking = new Parking();
//                    parking.setPid(jParking.optString("pid"));
//                    parking.setName(jParking.optString("name"));
//                    JSONArray jImgURLs = jParking.optJSONArray("imgURL");
//                    List<String> imgURLs = new ArrayList<>();
//                    if (jImgURLs != null) {
//                        for (int j = 0; j < jImgURLs.length(); j++) {
//                            imgURLs.add(jImgURLs.optString(j));
//                        }
//                    }
//                    parking.setImgURLs(imgURLs);
//                    parking.setLotSize(jParking.optInt("lotSize"));
//                    parking.setLocation(jParking.optString("location"));
//                    parking.setDistance(jParking.optString("distance"));
//                    parking.setLongitude(jParking.optDouble("longitude"));
//                    parking.setLatitude(jParking.optDouble("latitude"));
                    JSONArray jParkingLots = jParking.optJSONArray("parkingLots");
                    List<ParkingLot> parkingLots = new ArrayList<>();
                    for (int i = 0; i < jParkingLots.length(); i++){
                        JSONObject jParkingLot = jParkingLots.optJSONObject(i);
                        ParkingLot parkingLot = new ParkingLot();

                        parkingLot.setLotId(jParkingLot.optString("lotId"));
                        parkingLot.setName(jParkingLot.optString("name"));
                        parkingLot.setOccupiedTime(jParkingLot.optJSONArray("occupiedTime"));

                        JSONArray jImgURLs = jParkingLot.optJSONArray("lotImgURL");
                        List<String> imgURLs = null;
                        if (jImgURLs != null){
                            imgURLs = new ArrayList<>();
                            for (int j = 0; j < jImgURLs.length(); j++){
                                imgURLs.add(jImgURLs.optString(j));
                            }
                        }
                        parkingLot.setImgURLs(imgURLs);

                        parkingLots.add(parkingLot);
                    }
                    parking.setParkingLots(parkingLots);

                    bindLinearLayout(xRadioGroup, parkingLots);
                } else {
                    Toast.makeText(ParkingActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure() {
                Toast.makeText(ParkingActivity.this, "网络异常", Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if(timePicker.isShowing()){
                timePicker.dismiss();
                return true;
            } else {
                this.finish();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private void reserveParkingLotById(String lotId, String startTime, String endTime) throws JSONException {
        JSONObject fparam = new JSONObject();
        fparam.put("uid", MainActivity.user.getReserveSysId())
                .put("lotId", lotId)
                .put("startTime", startTime)
                .put("endTime", endTime);

        HttpRequest.post(URLConstant.HOST, "reserveParkingLotById", fparam, new HttpRequest.HttpRequestCallback() {
            @Override
            public void onSuccess(JSONObject response) {
                if (response.optInt("success") == 1){
                    Toast.makeText(ParkingActivity.this, "预约成功", Toast.LENGTH_LONG).show();
//                    TODO
                    finish();
                } else
                    Toast.makeText(ParkingActivity.this, response.optString("result"), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onFailure() {
                Toast.makeText(ParkingActivity.this, "网络异常", Toast.LENGTH_LONG).show();
            }
        });
    }
}
